package top.dancun.eascourse.service.impl;


//import com.alibaba.cloud.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import top.dancun.common.utils.PageUtils;
import top.dancun.common.utils.Query;

import top.dancun.eascourse.dao.ClassScheduleDao;
import top.dancun.eascourse.entity.ClassScheduleEntity;
import top.dancun.eascourse.entity.CourseEntity;
import top.dancun.eascourse.entity.StudentEntity;
import top.dancun.eascourse.entity.TeacherEntity;
import top.dancun.eascourse.exception.CourseConflictsException;
import top.dancun.eascourse.feign.service.BaseInfoFeignService;
import top.dancun.eascourse.feign.service.StudentFeignService;
import top.dancun.eascourse.feign.service.TeacherFeignService;
import top.dancun.eascourse.service.ClassScheduleService;


@Service("classScheduleService")
public class ClassScheduleServiceImpl extends ServiceImpl<ClassScheduleDao, ClassScheduleEntity> implements ClassScheduleService {

    @Autowired
    private TeacherFeignService teacherFeignService;

    @Autowired
    private StudentFeignService studentFeignService;

    @Autowired
    BaseInfoFeignService baseInfoFeignService;
    //MON 、星期二 TUE 、星期三 WED 、星期四 THU 、星期五 FRI 、星期六 SAT 、星期天 SUN。
    private final String[] weekDay = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
    private final String[] weekDayCh = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ClassScheduleEntity> page = this.page(
                new Query<ClassScheduleEntity>().getPage(params),
                new QueryWrapper<ClassScheduleEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 获取课表
     * @param params
     * @return
     */
    @Override
    public List<Map<String, ClassScheduleEntity>> getCurriculum(Map<String, String> params) {

        //TODO 修改数据库保存
        Map<String, String> mtemp = new HashMap<>();
        for (int i = 0; i < weekDay.length; i++) {
            mtemp.put(weekDay[i], weekDayCh[i]);
        }
        //查询班级、教师、或个人课表
        LambdaQueryWrapper<ClassScheduleEntity> wrapper = Wrappers.lambdaQuery();
        if(StringUtils.isBlank(params.get("userId"))){
            //查询班级课表
            wrapper.eq(StringUtils.isNotBlank(params.get("classId")),
                    ClassScheduleEntity::getClassId,
                    params.get("classId"));

        }else if(params.get("userId").length()>8){
            //根据学生id获取班级信息

            List<String> sids = new ArrayList<>();
            sids.add(params.get("userId"));
            //feign远程访问student服务
            PageUtils pageUtils = studentFeignService.getByIds(new HashMap<>(),sids,new ArrayList<>());
            pageUtils.getList().forEach(map->{
                StudentEntity student = JSON.parseObject(JSON.toJSONString(map),StudentEntity.class);
                params.put("classId",student.getCid());
            });
            //学生查询班级和自己选课
            wrapper.eq(StringUtils.isNotBlank(params.get("classId")),
                            ClassScheduleEntity::getClassId,
                            params.get("classId"))
                    .or()
                    .eq(StringUtils.isNotBlank(params.get("userId")),
                            ClassScheduleEntity::getStudentId,
                            params.get("userId"));

        }else{
            //教师查询课表
            wrapper.eq(StringUtils.isNotBlank(params.get("userId")),
                    ClassScheduleEntity::getTeacherId,
                    params.get("userId"));
        }




        ;

        //查询数据结果
        List<ClassScheduleEntity> list = this.baseMapper.getUserCurriculum(wrapper);
        //添加教师信息
        setTeacherInfo(list);

        //组装课表用的集合，一条数据为每天的第i节课（table展示）
        List<Map<String, ClassScheduleEntity>> curriculum = new ArrayList<>(12);
        //初始化集合
        for (int i = 0; i < 12; i++) {
            curriculum.add(new HashMap<String, ClassScheduleEntity>());
        }
        //迭代组装课表的集合 将课程信息放到对应的星期和课次
        ListIterator<Map<String, ClassScheduleEntity>> iterator = curriculum.listIterator();
        for (int i = 0; iterator.hasNext(); i++) {
            Map<String, ClassScheduleEntity> map = iterator.next();
            for (String s : weekDay) {

//                map.put(s, new ClassScheduleEntity());
                for (ClassScheduleEntity classSchedule : list) {
//                    将课程信息放到对应的星期和课次
                    if (Objects.equals(classSchedule.getWeek(), mtemp.get(s)) && Objects.equals(classSchedule.getClassTimes(), i + 1)) {
                        map.put(s, classSchedule);
                        break;
                    }
                }
            }
        }

        return curriculum;
    }

    /**
     * 获取我的课程
     * @param id
     * @return
     */
    @Override
    public PageUtils getMyCourse(String id,Map<String, Object> params) {
        IPage page =new Query<ClassScheduleEntity>().getPage(params);
        QueryWrapper<ClassScheduleEntity> wrapper = Wrappers.query();
        //判断教师还是学生访问
        if (id.length() > 5) {
            String classId;
            List<String> studentIdList = new ArrayList<>();
            studentIdList.add(id);
            PageUtils pu = studentFeignService.getByIds(new HashMap<>(),studentIdList,new ArrayList<>());
            if(pu.getList().size()==1){
                StudentEntity student = JSON.parseObject(JSON.toJSONString(pu.getList().get(0)),StudentEntity.class);
                classId = student.getCid();
            } else {
                classId = "";
            }
            wrapper.and(w->{
                w.eq("student_id",id).or().eq("class_id",classId);
            });
        } else {
            wrapper.eq("teacher_id", id);

        }
        wrapper.like(Objects.nonNull(params.get("courseName"))
                        &&StringUtils.isNotBlank(params.get("courseName").toString())
                , "course_name",
                params.get("courseName")==null?"":String.valueOf(params.get("courseName")));

        page = this.getBaseMapper().getMyCourse(wrapper,page);
        setTeacherInfo(page.getRecords());

        return new PageUtils(page);
    }

    /**
     * 获取所有课程
     * @return
     */
    @Override
    public PageUtils getAllCourse(Map<String, Object> params) {
        IPage page =new Query<ClassScheduleEntity>().getPage(params);
        QueryWrapper<ClassScheduleEntity> wrapper = Wrappers.query();
        wrapper.like(Objects.nonNull(params.get("courseName"))
                        &&StringUtils.isNotBlank(params.get("courseName").toString())
                , "course_name",
                params.get("courseName")==null?"":String.valueOf(params.get("courseName")));
        page = this.getBaseMapper().getMyCourse(wrapper,page);
        setTeacherInfo(page.getRecords());
        return new PageUtils(page);
    }

    /**
     * 获取教师所教的某一课程的所有学生
     *
     * @param uid
     * @return
     */
    @Override
    public PageUtils getStudent(Map<String,String> params,String uid) {
        List<ClassScheduleEntity> list = new ArrayList<>();
        //判断教师还是学生访问

        LambdaQueryWrapper<ClassScheduleEntity> wrapper = Wrappers.lambdaQuery();
        wrapper
                .eq(ClassScheduleEntity::getTeacherId, uid)
                .eq(ClassScheduleEntity::getCourseId,params.get("courseId"));
        list = this.getBaseMapper().getMyCourseAndStuC(wrapper);
        List<Integer> cids = new ArrayList<>();
        List<String> sids = new ArrayList<>();
        list.forEach(classScheduleEntity -> {
            if(Objects.equals(classScheduleEntity.getType(),"class")){
                cids.add(classScheduleEntity.getClassId());
            }else {
                sids.add(classScheduleEntity.getStudentId());
            }
        });
        // 根据班级和学号查询所有学生信息
        PageUtils studentList = studentFeignService.getByIds(params,sids,cids);


        return studentList;
    }

    @Override
    public void clear(List<Integer> ids) {
        LambdaQueryWrapper<ClassScheduleEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.in(ClassScheduleEntity::getClassId, ids);
        this.remove(wrapper);
    }


    private void setTeacherInfo(List<ClassScheduleEntity> list) {
        //准备存放查询课表里面任课老师的id集合
        List<String> teacherIds = new ArrayList<>();
        List<Integer> roomIds = new ArrayList<>();
        //将任课老师id存放到集合里面
        list.forEach(classScheduleEntity -> {
            teacherIds.add(classScheduleEntity.getTeacherId());
            roomIds.add(classScheduleEntity.getRoomId());
        });
        //远程调用教师教课，获取指定id集合的教师信息
        List<TeacherEntity> teacherList = teacherFeignService.listByIds(teacherIds);
        Map<Integer,String> rooms = baseInfoFeignService.listRoomByIds(roomIds);
        //循环迭代给课表设置任课老师姓名
        list.forEach(classScheduleEntity -> {
            for (TeacherEntity teacher : teacherList) {
                if (Objects.equals(teacher.getTid(), classScheduleEntity.getTeacherId())) {
                    classScheduleEntity.setTeacherName(teacher.getName());
                    break;
                }
            }
            //添加房间信息
            classScheduleEntity.setRoom(rooms.get(classScheduleEntity.getRoomId()));
        });


    }


    @Override
    public boolean saveClassSchedule(ClassScheduleEntity entity) throws CourseConflictsException {
        int i = lambdaQuery()
                .eq(ClassScheduleEntity::getTeacherId,entity.getTeacherId())
                .ne(ClassScheduleEntity::getRoomId,entity.getRoomId())
                .eq(ClassScheduleEntity::getWeek,entity.getWeek())
                .eq(ClassScheduleEntity::getClassTimes,entity.getClassTimes())
                .list().size();
        if(i!=0){
            throw new CourseConflictsException();
        }
        return super.save(entity);
    }

}